/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.geergenbein.azw.loader.transcription;

import org.geergenbein.azw.model.transcription.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.geergenbein.azw.dao.transcription.DialectDAOHibernate;
import org.geergenbein.azw.dao.transcription.TranscriptionSystemDAOHibernate;
import org.geergenbein.dao.DAOUtils;

/**
 *
 * @author andrew
 */
public class TranscriptionLoader {
    
    final static String[] MANDARIN_TRANSCRIPTION_SYSTEM_NAMES = new String[] { 
        "Zhuyin", "Wade-Giles", "MPS2", "Yale", "Tongyong Pinyin", 
        "Hanyu Pinyin", "Gwoyeu Romatzyh"
    };
    final static String[] CANTONESE_TRANSCRIPTION_SYSTEM_NAMES = new String[] {
            "jyutping"
    };

    private final static int ZHUYIN = 0;
    private final static int WADE_GILES = 1;
    private final static int MSP2 = 2;
    private final static int YALE = 3;
    private final static int TONGYONG_PINYIN = 4;
    private final static int HANYU_PINYIN = 5;
    private final static int GWOYEU1 = 6;
    private final static int GWOYEU2 = 7;
    private final static int GWOYEU3 = 8;
    private final static int GWOYEU4 = 9;
    private Dialect mandarinDialect;
    private Dialect cantoneseDialect;
    private TranscriptionSystem zyTs;
    private TranscriptionSystem wgTs;
    private TranscriptionSystem mps2Ts;
    private TranscriptionSystem yaleTs;
    private TranscriptionSystem typyTs;
    private TranscriptionSystem hypyTs;
    private TranscriptionSystem gyTs;
    
    private List<TranscriptionSystem> mandarinTranscriptionSystems = 
            new ArrayList();
    private List<TranscriptionSystem> cantoneseTranscriptionSystems = 
            new ArrayList();
    private Map<String, TonedCodePoint> mandarinCodePoints = 
            new HashMap<String, TonedCodePoint>();
    private Map<String, TonedCodePoint> cantoneseCodePoints = 
            new HashMap<String, TonedCodePoint>();

    private InputStream mandarinTranscriptionStream;
    private InputStream cantoneseTranscriptionStream;
    
    private final Log log = LogFactory.getLog(getClass()); 

    /*public TranscriptionLoader(EntityManager entityManager,
            String mandarinTranscriptionPath,
            String cantoneseTranscriptionPath) throws IOException
    {
        this(entityManager, new )
        this.em = entityManager;
        this.mandarinTranscriptionPath = mandarinTranscriptionPath;
        this.cantoneseTranscriptionPath = cantoneseTranscriptionPath;
    }*/

    public TranscriptionLoader(InputStream mandarinTranscriptionStream,
            InputStream cantoneseTranscriptionStream)
    {
        this.mandarinTranscriptionStream = mandarinTranscriptionStream;
        this.cantoneseTranscriptionStream = cantoneseTranscriptionStream;
    }

    private void addDialects() {
        DAOUtils.getInstance().getTransaction().begin();
        DialectDAOHibernate dialectDAO = DAOUtils.getInstance().
                getDialectDAO();
        mandarinDialect = dialectDAO.loadOrPersist("Mandarin");
        cantoneseDialect = dialectDAO.loadOrPersist("Cantonese");
        DAOUtils.getInstance().getTransaction().commit();
    }
    
    private void addTranscriptions(String[] names, Dialect dialect, 
            List<TranscriptionSystem> transcriptions) 
    {
        DAOUtils.getInstance().getTransaction().begin();
        TranscriptionSystemDAOHibernate transcriptionSystemDAO = 
                DAOUtils.getInstance().getTranscriptionSystemDAO();
        for (String name : names) {
            transcriptions.add(transcriptionSystemDAO.loadOrPersist(dialect, 
                    name));
        }
        DAOUtils.getInstance().getTransaction().commit();
    }

    public void loadMandarinTranscriptions() throws IOException {
        LineNumberReader reader = new LineNumberReader(
                new InputStreamReader(mandarinTranscriptionStream));
        String line;

        while ((line = reader.readLine()) != null) {
            DAOUtils.getInstance().getTransaction().begin();
            String[] transcriptions = line.split("\\s+");
            UntonedCodePoint ucp = DAOUtils.getInstance().
                    getUntonedCodePointDAO().loadOrPersist(mandarinDialect, 
                    transcriptions[HANYU_PINYIN]);
            
            TonedCodePoint[] tonedCodePoints = new TonedCodePoint[6];
            List tbe = new ArrayList();
            for (int i = 0; i < mandarinTranscriptionSystems.size(); i++) {
                UntonedTranscription ut = DAOUtils.getInstance().
                        getUntonedTranscriptionDAO().loadOrPersist(ucp, 
                        mandarinTranscriptionSystems.get(i), transcriptions[i]);
                for (int j = 1; j <= 5; j++) {
                    if (i == 0) {
                        // create the toned code point
                        String mandarinName = transcriptions[HANYU_PINYIN] + j;
                        tonedCodePoints[j] = DAOUtils.getInstance().
                                getTonedCodePointDAO().loadOrPersist(ucp, j, 
                                mandarinName);
                        getMandarinCodePoints().put(mandarinName, 
                                tonedCodePoints[j]);
                    }
                    TonedTranscription tt = null;
                    if (i < mandarinTranscriptionSystems.size() - 1) {
                        tt = DAOUtils.getInstance().
                                getTonedTranscriptionDAO().
                                loadOrPersist(tonedCodePoints[j],
                                    mandarinTranscriptionSystems.get(i), 
                                    transcriptions[i] + j);
                    } else {
                        tt = DAOUtils.getInstance().
                                getTonedTranscriptionDAO().
                                loadOrPersist(tonedCodePoints[j],
                                    mandarinTranscriptionSystems.get(i), 
                                    transcriptions[i + j < transcriptions.length ? i + j : i]);
                    }
                    tbe.add(tt);
                }
                tbe.add(ut);
            }
            
            DAOUtils.getInstance().getTransaction().commit();
            /*
            DAOUtils.getDAOUtils().evict(ucp);
            for (TonedCodePoint tcp : tonedCodePoints) {
                DAOUtils.getDAOUtils().evict(tcp);
            }
            for (Object obj : tbe) {
                DAOUtils.getDAOUtils().evict(obj);
            }
            tbe.clear();*/
            DAOUtils.getInstance().clear();
        }
    }

    public void loadCantoneseTranscriptions() throws IOException {
        LineNumberReader reader = new LineNumberReader(
                new InputStreamReader(cantoneseTranscriptionStream));
        String line;

        while ((line = reader.readLine()) != null) {
            DAOUtils.getInstance().getTransaction().begin();
            String transcription = line.trim();
            UntonedCodePoint ucp = DAOUtils.getInstance().
                    getUntonedCodePointDAO().loadOrPersist(cantoneseDialect, 
                    transcription);
            TonedCodePoint[] tonedCodePoints = new TonedCodePoint[7];
            List tbe = new ArrayList();
            for (int i = 0; i < cantoneseTranscriptionSystems.size(); i++) {
                //TranscriptionSystem ts = null;
                UntonedTranscription ut = DAOUtils.getInstance().
                        getUntonedTranscriptionDAO().loadOrPersist(ucp,
                        cantoneseTranscriptionSystems.get(i), transcription);
                for (int j = 1; j <= 6; j++) {
                    if (i == 0) {
                        // create the toned code point
                        String cantoneseName = transcription + j;
                        tonedCodePoints[j] = DAOUtils.getInstance().
                                getTonedCodePointDAO().loadOrPersist(ucp, j,
                                cantoneseName);
                        getCantoneseCodePoints().put(cantoneseName,
                                tonedCodePoints[j]);
                    }
                    TonedTranscription tt = null;
                    tt = DAOUtils.getInstance().
                                getTonedTranscriptionDAO().
                                loadOrPersist(tonedCodePoints[j],
                                    cantoneseTranscriptionSystems.get(i),
                                    transcription + j);
                    tbe.add(tt);
                }
                tbe.add(ut);
            }
            
            DAOUtils.getInstance().getTransaction().commit();
            /*
            DAOUtils.getDAOUtils().evict(ucp);
            for (TonedCodePoint tcp : tonedCodePoints) {
                DAOUtils.getDAOUtils().evict(tcp);
            }
            for (Object obj : tbe) {
                DAOUtils.getDAOUtils().evict(obj);
            }
            tbe.clear();
            */
            DAOUtils.getInstance().clear();
        }
    }

    public Map<String, TonedCodePoint> getMandarinCodePoints() {
        return mandarinCodePoints;
    }

    public Map<String, TonedCodePoint> getCantoneseCodePoints() {
        return cantoneseCodePoints;
    }

    public Dialect getMandarinDialect() {
        return mandarinDialect;
    }

    public Dialect getCantoneseDialect() {
        return cantoneseDialect;
    }
    
    public void load() throws IOException {
        
        addDialects();
        addTranscriptions(MANDARIN_TRANSCRIPTION_SYSTEM_NAMES, mandarinDialect, 
                mandarinTranscriptionSystems);
        addTranscriptions(CANTONESE_TRANSCRIPTION_SYSTEM_NAMES, 
                cantoneseDialect, cantoneseTranscriptionSystems);
        loadMandarinTranscriptions();
        loadCantoneseTranscriptions();
    }
    
}
